# coding: utf8

import os
import logging
import re
import traceback

import requests_html
from multiprocessing.pool import ThreadPool

""" 南京大学
电子工程系, 微电子与光电子学系
"""

logging.basicConfig(level=logging.INFO)

session = requests_html.HTMLSession()
pool = ThreadPool(os.cpu_count() * 2)

reduce_breaklines = re.compile(r'\n{2,}')
tel_ptn = re.compile(r'电话[:：]([0-9+\s\-]*?\n)')
email_ptn = re.compile(r'邮件[:：]([\s\S]+?\n)')
addr_ptn = re.compile(r'办公地址[:：]([\s\S]*?\n)')

ri_ptn = re.compile(r'(?:研究(?:方向|领域|重点)(?:为|包括)*|主要从事)[:：]*([\s\S]*?[。|\n])')
pos_ptn = re.compile(r"(教授|副教授|助理教授|研究员|副研究员|硕士导师|博士导师|研究生导师|博士生导师|硕导|博导|IEEE Fellow|博士)")
edu_ptn = re.compile(r"考入|攻读|进修|毕业于|学位|博士后")
split_ptn = re.compile(r'([.。\n])')


def teacher_list():
    try:
        r = session.get("https://ese.nju.edu.cn/30445/list.htm")
        if r.status_code == 200:
            container = r.html.xpath("//ul[@class='wp_subcolumn_list']/li[contains(@class,'wp_sublist sublist-2')][1]")
            container = container[0] if container else None
            # header = container.xpath("//h3[@class='sublist_title'][1]")  # 微电子与光电子学系

            teachers = []
            lis = container.xpath("//ul[contains(@class, 'news_list list2 clearfix')]/li")
            for li in lis:
                teachers.append((li.full_text.strip(), list(li.absolute_links)[0]))

            pool.imap_unordered(teacher_detail, teachers)

            pass
        else:
            logging.warning("status code error: %s", r.status_code)
            r.raise_for_status()
    except Exception as e:
        traceback.print_exc()
        raise e


def teacher_detail(payload):
    name, url = payload
    logging.info("load teacher %s ...", name)

    try:
        r = session.get(url)
        if r.status_code == 200:
            portletmode = r.html.xpath("//div[@frag='窗口103'][1]/@portletmode")
            portletmode = portletmode[0] if portletmode else None

            if portletmode == "simpleList":
                upper_table = r.html.xpath("//div[@frag='窗口103']//table")[0]
                avatar = "https://ese.nju.edu.cn" + upper_table.xpath("//div[@class='face']//img/@src")[0]

                name = upper_table.xpath("//div[@class='text']//h3/text()")[0]
                dep_pos = upper_table.xpath("//div[@class='text']//p/text()")[0].split()
                dep, simple_pos = dep_pos if len(dep_pos) == 2 else ("".join(dep_pos), '')

                contact_table = r.html.xpath("//div[@frag='窗口101']//table//div[@class='text']")[0]
                contacts = reduce_breaklines.sub('\n', contact_table.full_text)

                tel, email, addr = [ptn.search(contacts) for ptn in (tel_ptn, email_ptn, addr_ptn)]
                tel, email, addr = [(match.group(1).strip() if match else '') for match in (tel, email, addr)]

                logging.info("name: %s, dep: %s, pos: %s, tel: %s, email: %s, addr: %s, avatar: %s", name, dep, simple_pos, tel, email, addr, avatar)

                info_table = r.html.xpath("//div[@frag='窗口102']//table//tr[1]/td[1]")
                info_table = info_table[0] if info_table else None

                intro = info_table.xpath("//div[contains(@class, 'txt_1 tx')][1]//div[@class='text'][1]")[0].full_text
                ri = info_table.xpath("//div[contains(@class, 'txt_2 tx')][1]//div[@class='text'][1]")[0].full_text
                courses = info_table.xpath('//div[contains(@class, "txt_3 tx")][1]//div[@class="text"][1]')[0].full_text
                papers = info_table.xpath("//div[contains(@class, 'txt_4 tx')][1]//div[@class='text'][1]")[0].full_text

                pos = set(pos_ptn.findall(intro))
                if '教授' in pos:
                    pos.discard('助理教授')
                    pos.discard('副教授')
                    pos.discard('研究员')
                pos = list(pos)
                if not pos:
                    pos.append(simple_pos)
                pos = ",".join(pos)

                sentences = split_ptn.split(intro)
                edu_sent = []
                for sent in sentences:
                    if edu_ptn.search(sent):
                        edu_sent.append(sent)
                edu = "。".join(edu_sent)

                if ri.strip() == "":
                    ri = ri_ptn.search(intro)
                    ri = ri.group(1) if ri else ''

                logging.info("name: %s, pos, %s, edu: %s, intro: %s, ri: %s, courses: %s, papers: %s",
                             name, pos, edu, intro, ri, courses, papers)
            else:
                logging.info("%s contains no info.", name)

            pass
        else:
            logging.warning("status code error: %s", r.status_code)
            r.raise_for_status()
    except Exception as e:
        traceback.print_exc()
        raise e


if __name__ == '__main__':
    teacher_list()

    pool.close()
    pool.join()

    session.close()
    pass

